# 对应CSDN python系列专栏博客
# 写于2024 04 20
# 主题：Python函数的黑魔法：递归，嵌套函数与装饰器

# 一、参数传递的序列解包

# 解包列表
def func(x, y, z):
    return x + y + z


print(func(*[1, 2, 3]))
print(func(*(5, 9, 8)))


# 解包字典

def func2(name, age):
    print(f"Name: {name}, Age: {age}")


person = {'name': 'Alice', 'age': 25}

func2(**person)


# 递归函数
def Fib(n):
    if n < 2:
        return 1  # 第1，2个斐波那契数为1
    else:
        return Fib(n - 1) + Fib(n - 2)  # 递推关系：前两个斐波那契数之和


# 输出前10个斐波那契数
for i in range(10):
    print(Fib(i), end=" ")


# 嵌套函数
def outer_function(x):
    def inner_function(y):
        return y * 2

    return inner_function(x)  # 调用内部函数


result = outer_function(5)  # 调用外部函数
print(result)  # 输出 10


# 3.2 装饰器的定义和使用

# 装饰器的定义
def decorator(func):
    pass


@decorator
def func():
    pass


# 装饰器返回一个函数
def my_decorator(func):
    def wrapper():
        return func() + 1

    return wrapper


def my_function():
    return 3


my_function = my_decorator(my_function)

result = my_function()
print(result)


# 装饰器返回一个装饰器
def outer_decorator(option):
    if option == "A":
        def inner_decorator(func):
            def wrapper():
                return func()

            return wrapper
    elif option == "B":
        def inner_decorator(func):
            def wrapper():
                return func()

            return wrapper
    else:
        raise ValueError("Invalid option")

    return inner_decorator


@outer_decorator(option="A")
def ret1():
    return "Hello, world!"


@outer_decorator(option="B")
def ret2():
    return "Hello again!"


print(ret1())
print(ret2())


# 修改网页的文本格式
# 定义装饰器
def deco(func):
    # 定义内函数
    def modify_text(str):
        return "<strong>" + func(str) + "</strong>"

    return modify_text


# 使用装饰器修饰函数
@deco
def textFunc(str):
    return str


print(textFunc("text"))

# 四、变量作用域
global_v = "我是一个全局变量"


def outer_function():
    enclosing_v = "我是一个嵌套变量"

    def inner_function():
        local_v = "我是一个局部变量"
        print(local_v)
        print(enclosing_v)
        print(global_v)

    inner_function()


outer_function()
print(global_v)

# global 关键字

global_var = 10


def modify_global():
    global global_var
    global_var = 20


modify_global()
print(global_var)  # 输出 20


# nonlocal 关键字
def outer_function():
    outer_var = 10

    def inner_function():
        nonlocal outer_var
        outer_var = 20

    inner_function()
    print(outer_var)  # 输出 20


outer_function()

# 练习题答案
def sum(n):
    if n == 1:
        return 1
    else:
        return n + sum(n - 1)
